package study.itwill.common;

import java.util.Calendar;
import java.util.Locale;

/****************************************************************
 * 날짜 처리 유틸리티
 *
 * @author 이광호 (totory3217@gmail.com)
 * @version 1.0.0
 ****************************************************************/
public class DateTime {
	private static DateTime current = null;
	
	/*************************************************************
	 * 전역으로 사용할 싱글톤 객체를 생성한다.
	 * 
	 * [사용법]
	 * DateTime dt = DateTime.getInstance();
	 * String date = dt.getNowDateTimeString();
	 * ----- 혹은 -----
	 * String date = DateTime.getInstance().getNowDateTimeString();
	 *************************************************************/
	public static DateTime getInstance() {
		if (current == null) {
			current = new DateTime();
		}
		
		return current;
	}
	

	/*************************************************************
	 * 생성된 싱글톤 객체를 메모리에서 삭제한다.
	 *************************************************************/
	public static void freeInstance() {
		if (current != null) {
			current = null;
		}
	}
	
	
	/*************************************************************
	 * 현재 날짜와 시간을 yyyymmddhhmiss 형으로 리턴한다.
	 *
	 * @return String (yyyymmddhhmiss)
	 *************************************************************/
	public String getNowDateTimeString() {
		Calendar cal = Calendar.getInstance();
		int yy = cal.get(Calendar.YEAR);
		int mm = cal.get(Calendar.MONTH) + 1;
		int dd = cal.get(Calendar.DAY_OF_MONTH);
		int h = cal.get(Calendar.HOUR_OF_DAY);
		int m = cal.get(Calendar.MINUTE);
		int s = cal.get(Calendar.SECOND);
		cal = null;
		return String.format(Locale.getDefault(), "%04d%02d%02d%02d%02d%02d", yy, mm, dd, h, m, s);
	}

	/*************************************************************
	 * 현재 날짜와 시간을 파라미터로 전달된 포멧에 맞춰서 리턴한다.
	 *
	 * @return String (yyyymmddhhmiss)
	 *************************************************************/
	public String getNowDateTimeString(String p_szFormat) {
		Calendar cal = Calendar.getInstance();
		int yy = cal.get(Calendar.YEAR);
		int mm = cal.get(Calendar.MONTH) + 1;
		int dd = cal.get(Calendar.DAY_OF_MONTH);
		int h = cal.get(Calendar.HOUR_OF_DAY);
		int m = cal.get(Calendar.MINUTE);
		int s = cal.get(Calendar.SECOND);
		cal = null;
		return String.format(Locale.getDefault(), p_szFormat, yy, mm, dd, h, m, s);
	}

	/*************************************************************
	 * 현재 날짜를 int형 배열로 리턴한다.
	 *
	 * @return int[3]
	 *************************************************************/
	public int[] getNowDate() {
		int[] date = new int[3];
		Calendar cal = Calendar.getInstance();
		date[0] = cal.get(Calendar.YEAR);
		date[1] = cal.get(Calendar.MONTH) + 1;
		date[2] = cal.get(Calendar.DAY_OF_MONTH);
		cal = null;
		return date;
	}

	/*************************************************************
	 * 현재 시간을 int형 배열로 리턴한다.
	 *
	 * @return int[3]
	 *************************************************************/
	public int[] getNowTime() {
		int[] time = new int[3];
		Calendar cal = Calendar.getInstance();
		time[0] = cal.get(Calendar.HOUR_OF_DAY);
		time[1] = cal.get(Calendar.MINUTE);
		time[2] = cal.get(Calendar.SECOND);
		cal = null;
		return time;
	}

	/*************************************************************
	 * 현재 날짜와 시간을 int형 배열로 리턴한다.
	 *
	 * @return int[6]
	 *************************************************************/
	public int[] getNowDateTime() {
		int[] date = new int[6];
		Calendar cal = Calendar.getInstance();
		date[0] = cal.get(Calendar.YEAR);
		date[1] = cal.get(Calendar.MONTH) + 1;
		date[2] = cal.get(Calendar.DAY_OF_MONTH);
		date[3] = cal.get(Calendar.HOUR_OF_DAY);
		date[4] = cal.get(Calendar.MINUTE);
		date[5] = cal.get(Calendar.SECOND);
		cal = null;
		return date;
	}

	/*************************************************************
	 * YYYYMMDD 형식의 문자열을 숫자형태로 변환한다.
	 *
	 * @param p_szDate
	 *            날짜를 담는 문자열 (ex: 19820314)
	 *
	 * @return int[3]
	 *************************************************************/
	public int[] getDate(String p_szDate) {
		if (p_szDate.length() < 8) {
			return null;
		}

		int[] date = new int[3];

		date[0] = Integer.parseInt(p_szDate.substring(0, 4));
		date[1] = Integer.parseInt(p_szDate.substring(4, 6));
		date[2] = Integer.parseInt(p_szDate.substring(6, 8));

		return date;
	}

	/*************************************************************
	 * YYYYMMDD 형식의 문자열을 정해진 포멧으로 변환한다.
	 *
	 * @param p_szDate
	 *            날짜를 담는 문자열 (ex: 19820314)
	 * @param p_szFormat
	 *            날짜를 담기 위한 포멧 (ex: %04d-%02d-%02d)
	 *
	 * @return String
	 *************************************************************/
	public String getDate(String p_szDate, String p_szFormat) {
		int[] date = getDate(p_szDate);

		if (date == null) {
			return null;
		}

		return String.format(Locale.getDefault(), p_szFormat, date[0], date[1], date[2]);
	}

	/*************************************************************
	 * HHMISS 형식의 문자열을 숫자배열형태로 변환한다.
	 *
	 * @param p_szTime
	 *            시간을 담는 문자열 (ex: 023041)
	 *
	 * @return int[3]
	 *************************************************************/
	public int[] getTime(String p_szTime) {
		if (p_szTime.length() < 6) {
			return null;
		}

		int[] time = new int[3];

		time[0] = Integer.parseInt(p_szTime.substring(0, 2));
		time[1] = Integer.parseInt(p_szTime.substring(2, 4));
		time[2] = Integer.parseInt(p_szTime.substring(4, 6));

		return time;
	}

	/*************************************************************
	 * HHMISS 형식의 문자열을 정해진 포멧으로 변환한다.
	 *
	 * @param p_szTime
	 *            시간을 담는 문자열 (ex: 023041)
	 * @param p_szFormat
	 *            시간을 담기 위한 포멧 (ex: %02d:%02d:%02d)
	 *
	 * @return String
	 *************************************************************/
	public String getTime(String p_szTime, String p_szFormat) {
		int[] time = getTime(p_szTime);

		if (time == null) {
			return null;
		}

		return String.format(Locale.getDefault(), p_szFormat, time[0], time[1], time[2]);
	}

	/*************************************************************
	 * YYYYMMDDHHMISS 형식의 문자열을 숫자 배열 형태로 변환한다.
	 *
	 * @param p_szDateTime
	 *            날짜와 시간을 담는 문자열 (ex: 19820314013012)
	 *
	 * @return int[6]
	 *************************************************************/
	public int[] getDateTime(String p_szDateTime) {
		if (p_szDateTime.length() != 14) {
			return null;
		}

		int[] datetime = new int[6];

		datetime[0] = Integer.parseInt(p_szDateTime.substring(0, 4));
		datetime[1] = Integer.parseInt(p_szDateTime.substring(4, 6));
		datetime[2] = Integer.parseInt(p_szDateTime.substring(6, 8));
		datetime[3] = Integer.parseInt(p_szDateTime.substring(8, 10));
		datetime[4] = Integer.parseInt(p_szDateTime.substring(10, 12));
		datetime[5] = Integer.parseInt(p_szDateTime.substring(12, 14));

		return datetime;
	}

	/*************************************************************
	 * YYYYMMDDHHMISS 형식의 문자열을 정해진 포멧으로 변환한다.
	 *
	 * @param p_szDateTime
	 *            날짜와 시간을 담는 문자열 (ex: 19820314013012)
	 * @param p_szFormat
	 *            시간을 담기 위한 포멧 (ex: %04d-%04d-%04d %02d:%02d:%02d)
	 *
	 * @return String
	 *************************************************************/
	public String getDateTime(String p_szTime, String p_szFormat) {
		int[] datetime = getDateTime(p_szTime);

		if (datetime == null) {
			return null;
		}

		return String.format(p_szFormat, datetime[0], datetime[1], datetime[2],
				datetime[3], datetime[4], datetime[5]);
	}

	/*************************************************************
	 * YYYYMMDDHHMISS 형식의 문자열을 yyyy-mm-dd hh:mi:ss 포멧으로 변환한다.
	 *
	 * @param p_szDateTime
	 *            날짜와 시간을 담는 문자열 (ex: 19820314013012)
	 *
	 * @return String
	 *************************************************************/
	public String getDateTimeString(String p_szDateTime) {
		return getDateTime(p_szDateTime, "%04d-%02d-%02d %02d;%02d;%02d");
	}

	/*************************************************************
	 * YYMMDD 형식의 문자열에서 요일 인덱스를 리턴한다.
	 *
	 * @param p_szDate
	 *            날짜를 담는 문자열 (ex: 19820314)
	 *
	 * @return int (1=일,7=토)
	 *************************************************************/
	public int getDayIndex(String p_szDate) {
		int nDay = 0;
		if (p_szDate.length() > 8) {
			p_szDate = p_szDate.substring(0, 8);
		}

		int[] date = getDate(p_szDate);

		if (date != null) {
			Calendar c = Calendar.getInstance();
			c.set(date[0], date[1] - 1, date[2]);
			nDay = c.get(Calendar.DAY_OF_WEEK);
		}

		return nDay;
	}

	/*************************************************************
	 * YYMMDD 형식의 문자열에서 요일을 의미하는 3글자로 구성된 영문 문자열을 리턴한다.
	 *
	 * @param p_szDate
	 *            날짜를 담는 문자열 (ex: 19820314)
	 *
	 * @return String
	 *************************************************************/
	public String getDayStringEng(String p_szDate) {
		String data[] = new String[] { "SUN", "MON", "TUE", "WED", "THU",
				"FRI", "SAT" };
		return data[getDayIndex(p_szDate) - 1];
	}

	/*************************************************************
	 * YYMMDD 형식의 문자열에서 요일을 의미하는 문자열을 한글로 리턴한다.
	 *
	 * @param p_szDate
	 *            날짜를 담는 문자열 (ex: 19820314)
	 *
	 * @return String
	 *************************************************************/
	public String getDayStringKor(String p_szDate) {
		String data[] = new String[] { "일", "월", "화", "수", "목", "금", "토" };
		return data[getDayIndex(p_szDate) - 1];
	}
}
